con

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

  MAX_BUFF      = 256
  TIMEOUT       = 100
  TEMP_BUFF_LEN = 16

var

  byte  connected
  byte  inbuff[MAX_BUFF]
  byte  temp_buff1[TEMP_BUFF_LEN]
  byte  temp_buff2[TEMP_BUFF_LEN]
  byte  temp_buff3[TEMP_BUFF_LEN]
  byte  program_mode
  

obj

  xb    :       "FullDuplexSerial"
  device:       "FullDuplexSerial"
' d     :       "Parallax Serial Terminal"

dat

pc_host       byte      "PC_HOST", 0            'this string should be the node identifier of the xbee that is connected to your host computer

ok            byte      "OK", 0
command_mode  byte      "+++", 0
node_discover byte      "ATND", 13, 0

program_mode_str byte   "!!XBEEPROG__",0




pub go | i, j, prog_seq, buff_count, inbyte

  '==== program logic for xbee/ethernet propeller programmer ====

  'check for connection with host
  'wait for command
  'on receipt of program command, begin to buffer data
  'buffer and write to upper eeprom space
  'once the complete image is buffered, validate with host
  'begin programming sequence

  xb.start(26,27,0,9_600)
  device.start(31,30,%000,115_200)
  'd.start(115_200)

  'receive programming start sequence
  'if sequence is incorrect

  repeat

    inbyte := xb.rxtime(TIMEOUT)

    if inbyte == "!" and !buff_count
      prog_seq~~
      temp_buff1[buff_count] := inbyte
      buff_count++
      next
    
    if inbyte == -1          'if we timed out on any byte, then we arent going into the programming sequence
      prog_seq~

    if !prog_seq and buff_count > 0
      repeat i from 0 to buff_count -1
        'dump what was pulled into the buffer

    if prog_seq
      temp_buff1[buff_count]

      if buff_count > 0
        if temp_buff1[buff_count] == byte[@program_mode_str + buff_count]
          if buff_count == strsize(@program_mode_str)
            program_mode~~
      
      buff_count++
      


    
  

  {
  waitcnt(cnt + clkfreq<<2)
  d.str(string("entering command mode",13))
  'd.char(13)
  xb.str(@command_mode)         'put the xbee into command mode
  d.str(string("sent",13))
  read_input_non_blocking
  d.str(string("done waiting",13))
  d.str(@inbuff)
    
  if strcomp(@inbuff, @ok)      'entered command mode OK
    xb.str(@node_discover)      'now send the node discover command

  read_input_wait_on_cr

  i~                            
  repeat until inbuff[i++] == 13    'discard first line
  repeat j from 0 to 7
    temp_buff1[j] := inbuff[i++]    'get serial high
  temp_buff1[8] := 0
  repeat j from 0 to 7
    temp_buff2[j] := inbuff[i++]    'get serial low
  temp_buff2[8] := 0
  j~
  repeat until inbuff[i] == 13
    temp_buff3[j++] := inbuff[i++]  'get node identifier
  temp_buff1[j] := 0

  d.clear
  d.str(@temp_buff1)
  d.char(13)
  d.str(@temp_buff2)
  d.char(13)
  d.str(@temp_buff3)
  d.char(13)
    

  } 
    
    
    
pub read_input_non_blocking | i, val

  'description: reads input from the xbee.  NON-Blocking.
  '   If serial communication times out, then an empty
  '   null terminiated string will be left in inbuff.
  '   This method is destructive to inbuff.

  inbuff[0] := val := xb.rx
  
  repeat i from 1 to MAX_BUFF - 1
    inbuff[i] := val := xb.rxtime(TIMEOUT)
    
    if val == -1          'if we timed out on any byte...
      inbuff[i] := 0            '...null terminate the buffer
      quit                      'hop out of our loop
  
  
pub read_input_wait_on_cr | last_ch, i

  'description: reads input from the xbee.  Blocking.
  '  Will block execution until two consecutive cariage
  '  returns are read.  Results are left in inbuff.

  last_ch~
  
  repeat i from 0 to MAX_BUFF - 1
    inbuff[i] := xb.rx
    if last_ch == 13 and inbuff[i] == 13
      quit
    last_ch := inbuff[i]
    
  inbuff[i] := 0
    

